#!/usr/bin/env node
// A minimal, dependency-free HTTP benchmark script.
// Usage: node simple-bench.js -c 50 -d 10 http://localhost:3000/api/hello

const http = require('http');
const https = require('https');
const { URL } = require('url');

function parseArgs(argv) {
  const args = { connections: 10, duration: 5, url: null };
  const rest = [];
  for (let i = 2; i < argv.length; i++) {
    const a = argv[i];
    if (a === '-c' || a === '--connections') { args.connections = parseInt(argv[++i], 10); continue; }
    if (a === '-d' || a === '--duration') { args.duration = parseInt(argv[++i], 10); continue; }
    rest.push(a);
  }
  if (rest.length) args.url = rest[0];
  return args;
}

const opts = parseArgs(process.argv);
if (!opts.url) {
  console.error('Usage: node simple-bench.js -c <connections> -d <seconds> <url>');
  process.exit(1);
}

const url = new URL(opts.url);
const isHttps = url.protocol === 'https:';
const lib = isHttps ? https : http;

const latencies = [];
let total = 0;
let errors = 0;

function requestOnce() {
  return new Promise((resolve) => {
    const start = Date.now();
    const req = lib.request(
      {
        hostname: url.hostname,
        port: url.port || (isHttps ? 443 : 80),
        path: url.pathname + (url.search || ''),
        method: 'GET',
        timeout: 5000,
      },
      (res) => {
        // consume response
        res.on('data', () => {});
        res.on('end', () => {
          const ms = Date.now() - start;
          latencies.push(ms);
          total++;
          resolve();
        });
      }
    );
    req.on('error', () => { errors++; resolve(); });
    req.on('timeout', () => { req.abort(); errors++; resolve(); });
    req.end();
  });
}

async function worker(endAt) {
  while (Date.now() < endAt) {
    await requestOnce();
  }
}

async function run() {
  const endAt = Date.now() + opts.duration * 1000;
  const conns = Math.max(1, opts.connections);
  console.log(`Running bench: ${conns} connections for ${opts.duration}s against ${opts.url}`);
  const workers = [];
  for (let i = 0; i < conns; i++) workers.push(worker(endAt));
  await Promise.all(workers);

  // compute stats
  latencies.sort((a,b)=>a-b);
  const sum = latencies.reduce((s,v)=>s+v,0);
  const mean = latencies.length ? sum / latencies.length : 0;
  function pct(p) {
    if (!latencies.length) return 0;
    const idx = Math.floor((p/100) * latencies.length);
    return latencies[Math.min(idx, latencies.length-1)];
  }

  console.log('--- Results ---');
  console.log('requests:', total);
  console.log('errors:', errors);
  console.log('mean (ms):', mean.toFixed(2));
  console.log('p50 (ms):', pct(50));
  console.log('p95 (ms):', pct(95));
  console.log('p99 (ms):', pct(99));
  console.log('max (ms):', latencies.length ? latencies[latencies.length-1] : 0);
  console.log('requests/sec (approx):', (total / opts.duration).toFixed(2));
}

run().catch(err=>{ console.error(err); process.exit(2); });
